#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

// PE 文件头结构定义（简化版）
#pragma pack(push, 1)
typedef struct {
    uint16_t e_magic;      // DOS 头部魔数 "MZ"
    uint16_t e_cblp;
    // ... 其他字段省略 ...
    uint32_t e_lfanew;     // PE 头偏移量
} IMAGE_DOS_HEADER;

typedef struct {
    uint32_t Signature;    // PE 签名 "PE\0\0"
    uint16_t Machine;      // 目标架构标识
    // ... 其他字段省略 ...
} IMAGE_FILE_HEADER;
#pragma pack(pop)

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "用法: %s <exe文件路径>\n", argv[0]);
        return 1;
    }

    FILE *file = fopen(argv[1], "rb");
    if (!file) {
        perror("无法打开文件");
        return 1;
    }

    // 读取 DOS 头
    IMAGE_DOS_HEADER dosHeader;
    if (fread(&dosHeader, sizeof(dosHeader), 1, file) != 1) {
        fprintf(stderr, "读取 DOS 头失败\n");
        fclose(file);
        return 1;
    }

    // 验证 DOS 头部魔数
    if (dosHeader.e_magic != 0x5A4D) { // "MZ"
        fprintf(stderr, "无效的 DOS 头部\n");
        fclose(file);
        return 1;
    }

    // 跳转到 PE 头位置
    if (fseek(file, dosHeader.e_lfanew, SEEK_SET) != 0) {
        perror("定位 PE 头失败");
        fclose(file);
        return 1;
    }

    // 读取 PE 签名和文件头
    uint32_t peSignature;
    IMAGE_FILE_HEADER fileHeader;

    if (fread(&peSignature, sizeof(peSignature), 1, file) != 1) {
        fprintf(stderr, "读取 PE 签名失败\n");
        fclose(file);
        return 1;
    }

    if (peSignature != 0x00004550) { // "PE\0\0"
        fprintf(stderr, "无效的 PE 签名\n");
        fclose(file);
        return 1;
    }

    if (fread(&fileHeader, sizeof(fileHeader), 1, file) != 1) {
        fprintf(stderr, "读取文件头失败\n");
        fclose(file);
        return 1;
    }

    // 判断架构
    switch (fileHeader.Machine) {
        case 0x014c:
            printf("32 bit (x86) 可执行文件\n");
            break;
        case 0x8664:
            printf("64 bit(x64) 可执行文件\n");
            break;
        default:
            printf("未知架构 (0x%04x)\n", fileHeader.Machine);
            break;
    }

    fclose(file);
    return 0;
}